    <h1 class="pageHeader">Spica Framework - Manual - Hand-on guide</h1>

    <h2 class="header">Hướng dẫn cơ bản (Tutorial) - Simple Theme</h2>
    <p>Trong <a class="hasIcon" href="docs/guide/page/pname/tutorial_simplepage">bài trước</a>, quý vị
    đã làm quen với cơ chế làm việc với từng trang riêng lẻ trong Spica. Tuy nhiên cơ chế này
    không cho phép sử dụng lại một kết cấu chung mà nhiều trang có thể dùng lại. Spica hỗ trợ
    một cơ chế cho phép định nghĩa một kết cấu trang chung cho nhiều trang riêng lẻ khác nhau.
    Đây chính là mục tiêu của bài hướng dẫn này.</p>
    <h3>Khái niệm chung</h3>
    <p>Việc tạo ra một kiểu trình bày chung cho nhiều trang trong Spica có tên là <code>layout</code>. File chứa
    mã (thường chủ yếu là HTML) gọi là layout template. </p>
    <p>Việc nhóm nhiều layout thành một khối để hình thành nên một triết lý hay một phong
    cách trình bày cho toàn bộ site trong Spica gọi là theme. (xem thêm <a href="docs/guide/page/pname/concept_view" class="hasIcon">Các khái niệm về View:
    Theme, Template, Layout, Block, BlockGroup</a>)</p>
    <p>Theme là một chủ đề quan trọng trong thiết kế và phát triển các ứng dụng web. Nhìn từ góc độ
    người dùng, theme giúp tạo ra một cảm giác chung về một phong cách trình bày bao quát cho
    toàn bộ site. Nhìn từ góc độ người phát triển, theme giúp tổ chức site thành nhiều phong cách
    trong đó mỗi phong cách, đặc trưng bởi theme, có sự gắn kết và dùng chung các tài nguyên như
    hình ảnh, file CSS, các cấu trúc trang thống nhất thành một khối có thể thay thế cho nhau
    và phân phối được. Các ví dụ cụ thể theme có thấy từ việc phân phối các Joomla templates,
    Drupal theme ...<p>
    <p>Trong Spica, theme được hiểu như là một tập hợp các file PHP/HTML template, CSS, JS, ảnh, flash,
    các thư mục con nằm trong một thư mục có tên trùng với tên theme. <code>theme</code> được nạp thông
    qua Controller. Dưới sự điều khiển của framework, các thành phần của theme được tổ chức chặt
    chẽ nhằm giúp người phát triển có được một kiến trúc nhất quán trong việc xây dựng, chuyển đổi
    qua lại các theme khi cần thiết. Các thành phần chủ yếu bao gồm:</p>
    <ul>
      <li>Các file template gồm 3 loại: file template có phần mở rộng là <code>.tpl.php</code> dùng
      cho layout page, partial template và template đơn, và các file template nhằm nạp các mã CSS, JavaScript
      và meta tags vào layout page</li>
      <li>Các file CSS</li>
      <li>Các file JavaScript</li>
      <li>Các file hình ảnh</li>
    </ul>
    <p>Trong bài này, chúng ta sẽ cùng nhau phân tích cách xây dựng một theme từ các thành phần trên.</p>

    <h3>Cấu trúc thư mục của theme</h3>
    <p>Khi xây dựng một theme mới, người lập trình sẽ được yêu cầu tạo ra một cấu trúc thư mục như sau:</p>
    <ul>
      <li><strong>apps/default/view/theme/</strong><code class="bordered">theme_name</code>: tên theme chỉ
      gồm chữ La Tinh A-Z và số. Dưới đây là các thư mục con của thư mục <code class="bordered">theme_name</code>
        <ul>
          <li><strong>block</strong>: chứa các file template của thành phần block có phần mở rộng là <code>.tpl.php</code></li>
          <li><strong>blockgroup</strong>: chứa các file template của thành phần blockgroup có phần mở rộng là <code>.tpl.php</code></li>
          <li><strong>css</strong>: HTML/PHP template chứa các thẻ như <code>&lt;link&gt;</code>
          hay <code>&lt;style&gt;</code> để nạp các mã CSS vào trang.</li>
          <li><strong>js</strong>: HTML/PHP template chứa các thẻ như <code>&lt;script&gt;</code>
          để nạp các mã JavaScript vào trang.</li>
          <li><strong>layout</strong>: thư mục này chứa các layout page với phần mở rộng là <code>.tpl.php</code>.
          Các file ở đây được gọi từ Controller</li>
          <li><strong>meta</strong>: Các file chứa các đoạn mã HTML's <code>&lt;meta&gt;</code> dùng để tạo custom
          meta header cho từng trang (nếu cần)</li>
          <li><strong>page</strong>: Template từng trang riêng lẻ và chúng ta biết từ bài trước.</li>
          <li><strong>partial</strong>: Các file <code>.tpl.php</code> chứa một đoạn template dùng để nạp vào
          một file template khác. Thông thường các file ở đây có chứa mã PHP để xử lý phần dữ liệu truyền
          vào từ file template gọi cho nó.</li>
          <li><strong>ui</strong>: Template của các widget component mà người dùng tự định nghĩa
          hay cài đặt lại template của Spica widget component.</li>
        </ul>
      </li>
      <li><strong>public/theme/</strong><code class="bordered">theme_name</code>: thư mục chứa các file và
      thư mục con chứa các file tĩnh: CSS, JavaScript, Flash, ảnh (jpg, png, gif ...)
        <ul>
          <li><strong>css</strong>: nơi chứa các file <code>.css</code></li>
          <li><strong>js</strong>: nơi chứa các file <code>.js</code></li>
          <li><strong>image</strong>: nơi chứa các file hình ảnh</li>
        </ul>
      </li>
    </ul>

    <h3>Cấu hình sử dụng theme</h3>
    <p>Trong kiến trúc HMVC của Spica, <code>theme</code> là một phần của <code>View</code>.
    Nó có quan hệ 1-1 đối với ứng dụng chạy trên Spica. Nghĩa là tại một thời điểm thì
    chỉ có một theme được cấu hình để hỗ trợ cho ứng dụng. Theo cách này, theme sẽ được
    ghi vào trong hệ thống cấu hình trung tâm nằm trong file <code>apps/default/config/config.php</code>.
    Trong <a class="hasIcon" title="Tutorial - Simple page" href="docs/guide/page/pname/tutorial_simplepage">bài trước</a>,
    chúng ta đã biết rằng, cấu hình của mỗi ứng dụng trong Spica được ghi vào trong
    biến mảng cấu hình <code>$GLOBALS['__profiles__']</code> và <code>theme</code>
    chính là cái mà chúng ta cần quan tâm. Đây chính là tên của theme, trùng tên với tên
    thư mục chứa các file liên quan.</p>

<pre class="brush: php; highlight: [10];">
$GLOBALS['__profiles__'] = array(
// Context 'app0' - default Spica framework context
  'app0' =&gt; array(
     'function_namespace' =&gt; 'spica',
     'default_package'    =&gt; 'welcome',
     'default_module'     =&gt; 'home',
     'default_controller' =&gt; 'index',
     'default_action'     =&gt; 'index',
     'backup_route'       =&gt; array(),
     'theme'              =&gt; 'welcome',
     'image_base_path'    =&gt; null, // null means using the default path (theme specific)
     'js_base_path'       =&gt; null, // null means using the default path (theme specific)
     'css_base_path'      =&gt; null, // null means using the default path (theme specific)
     'flash_base_path'    =&gt; null, // null means using the default path (theme specific)
     'debug'              =&gt; false,
     'locale_string'      =&gt; 'vi_VN',
     'locale_charset'     =&gt; 'UTF8',
     'error'              =&gt; 'e1'),
</pre>
    <p>Chúng ta thay cấu hình mặc định trên thành <code>'theme' =&gt; 'my_theme'</code>. Sau đó chúng ta
    cũng cần có một thư mục có tên là <code>my_theme</code> nằm trong <code>apps/default/view/theme</code> (đường dẫn tuyệt đối là
    <code class="bordered">site_root/</code><code>apps/default/view/theme/my_theme</code>. Như vậy chúng ta sẽ tạo ra một
    cấu trúc như mục như sau:</p>
    <ul>
      <li><strong>apps/default/view/theme/</strong><code class="bordered">my_theme</code>
        <ul>
          <li><strong>block</strong></li>
          <li><strong>blockgroup</strong></li>
          <li><strong>css</strong></li>
          <li><strong>js</strong></li>
          <li><strong>layout</strong></li>
          <li><strong>meta</strong></li>
          <li><strong>page</strong></li>
          <li><strong>partial</strong></li>
          <li><strong>ui</strong></li>
        </ul>
      </li>
      <li><strong>public/theme/</strong><code class="bordered">my_theme</code>
        <ul>
          <li><strong>css</strong></li>
          <li><strong>js</strong></li>
          <li><strong>image</strong></li>
        </ul>
      </li>
    </ul>

    <h3>Cấu trúc của một trang layout</h3>
    <p>Một trang layout gồm các thành phần sau:</p>
    <ul>
      <li>Mã HTML xác định cấu trúc chung của toàn bộ trang</li>
      <li>Các vùng dữ liệu động (<strong>placeholder</strong>)
        <ul>
          <li>Các block (tùy chọn): là một vùng HTML được sinh ra bởi một lớp PHP nằm
          trong thư mục <code>apps/default/block</code>
          </li>
          <li>Các blockgroup (tùy chọn): là một vùng HTML được sinh ra bởi một lớp PHP nằm
          trong thư mục <code>apps/default/blockgroup</code></li>
          <li>Vùng body (tùy chọn nhưng thường có): là vùng HTML được sinh ra bởi một block
          hay một blockgroup</li>
          <li>Các thẻ HTML chứa mã JavaScript (tùy chọn): được sinh ra từ việc nạp 1 hay nhiều
          file có đuôi <code>.js.php</code> do controller xác định</li>
          <li>Các thẻ HTML chứa mã CSS (tùy chọn): được sinh ra từ việc nạp 1 hay nhiều file
          có đuôi <code>.css.php</code> do controller xác định</li>
          <li>Các thẻ HTML chứa meta header (tùy chọn): được sinh ra từ việc nạp 1 hay nhiều file
          có đuôi <code>.meta.php</code> do controller xác định</li>
        </ul>
      </li>
    </ul>
    <p>Placeholder là các vùng HTML mà nội dung của nó hoàn toàn động do các thành phần thuộc View layer
    bên ngoài layout page cung cấp. Spica phân biệt hai cách đọc nội dung từ placeholder</p>
    <ul>
      <li>Đọc trực tiếp: API dạng này cho phép gọi một thành phần cung cấp nội dung trực tiếp
      vào layout page mà không thông qua controller nhờ việc biết tên của chúng.
      Ví dụ: <code>fetchBlock()</code> và <code>fetchBlockGroup()</code></li>
      <li>Đọc gián tiếp: API dạng này cho phép gọi một thành phần cung cấp nội dung trực tiếp
      vào layout page mà nhưng không hề biết tên thành phần này là gì mà phải thông qua controller.
      Ví dụ: <code>fetchBody()</code>, <code>loadScript()</code>, <code>loadMeta()</code>, <code>loadCss()</code></li>
    </ul>
    <p>Nguyên tắc tạo trang này sẽ được cụ thể hóa ở phần dưới đây.</p>
    <h3>Tạo layout page</h3>
    <p>Trong kiến trúc theme của Spica, layout page là thành phần trung tâm tạo ra các kiểu
    tổ chức giao diện. Các file template của nó nằm trong thư mục <code>apps/default/view/theme/my_theme/layout</code>.
    Để cho đơn giản, chúng ta sẽ cùng nhau xây dựng một trang layout gồm có 3 phần: header của
    trang (giống nhau ở mọi trang), footer của trang (giống nhau ở mọi trang) và phần body, thay
    đổi theo từng trang. Trang layout này sẽ liên kết với một số file CSS tĩnh, giống nhau
    ở mọi trang nhưng sẽ lại có một số file CSS khác thay đổi theo từng trang.
    Chúng ta hãy tạo ra một file template như sau:</p>

<pre class="brush: php; highlight: [8, 9, 20]">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
&lt;?php echo spica_view_base_tag(); ?&gt;
&lt;title&gt;&lt;?php echo $this-&gt;pageTitle; ?&gt;&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;link rel="stylesheet" href="public/spica/css/reset.css" type="text/css" media="all" /&gt;
&lt;?php $this-&gt;loadMeta(); ?&gt;
&lt;?php $this-&gt;loadCss(); ?&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="wrapper"&gt;
  &lt;div&gt;Header of the page&lt;/div&gt;
  &lt;div id="main"&gt;
    &lt;div&gt;Main body content of the page&lt;/div&gt;
  &lt;/div&gt;
  &lt;div&gt;Footer of the page&lt;/div&gt;
&lt;/div&gt;
&lt;script type="text/javascript" src="public/spica/js/spica.js"&gt;&lt;/script&gt;
&lt;?php echo $this-&gt;loadScript(); ?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

    <p>Chúng ta sẽ lưu file này vào một file có tên là <code>index.tpl.php</code> và đặt vào
    <code>apps/default/view/theme/my_theme/layout</code>. Hãy chú ý đến các dòng được tô đậm.</p>
    <ul>
      <li>Dòng 8: <code>&lt;?php $this-&gt;loadMeta(); ?&gt;</code>: nghĩa là nạp đoạn
      mã meta tag nằm trong file được chỉ định tại controller.</li>
      <li>Dòng 9: <code>&lt;?php $this-&gt;loadCss(); ?&gt;</code>: nghĩa là nạp đoạn
      mã style tag hay link nằm trong file được chỉ định tại controller để đưa nội dung CSS vào.</li>
      <li>Dòng 8: <code>&lt;?php $this-&gt;loadScript(); ?&gt;</code>: nghĩa là nạp các file
      chứa mã JavaScript (nằm trong các script tag) được chỉ định tại controller.</li>
    </ul>
    <p>Các thành phần như block, blockgroup hay JavaScript ... là tùy chọn đối với một layout page.
    Một layout hoàn toàn có thể giống như một template page thông thường mà chúng ta
    biết ở <a class="hasIcon" href="docs/guide/page/pname/tutorial_simplepage">bài trước</a>.
    Tuy nhiên, layout page là một cấu trúc tổng quát cho một số trang nhất định cho nên Spica giúp chúng
    có thể vận hành một số nội dung động, có thể thay đổi theo từng bối cảnh, trong khi vẫn duy trì một
    cấu trúc chung. Đó là vai trò của các placeholder. Trong phần dưới đây, chúng ta sẽ cùng xem xét
    cách thức tạo ra các controller điều khiển các placeholder trên layout page này.</p>

    <h3>Sử dụng theme từ Controller</h3>
    <p>Chúng ta đã cùng nhau xem xét
    cách thức cấu hình sử dụng một theme cho toàn bộ site tại mục <strong>Cấu hình sử dụng theme</strong>.
    Qua đó chúng ta cũng đã thấy rằng một controller có thể sử dụng nhiều theme nhưng về
    nguyên tắc sẽ chỉ có 1 theme tham gia vào quá trình hiện thị trang tại cùng một thời điểm.
    Sau đây là cách thức controller gọi các tài nguyên của theme để xây dựng trang:</p>

<pre class="brush: php; highlight: [10, 12, 13, 14]">
&lt;?php

/**
 * &quot;Hello World&quot; program controller.
 */
 class Welcome_SamplePrint
 {
     public function helloworldAction()
     {
        $theme = SpicaContext::getTheme();
        $theme-&gt;pageTitle = 'Simple theme';
        $theme-&gt;attachCss('index');
        $theme-&gt;attachMeta('index');
        $theme-&gt;attachScript('index');
        SpicaResponse::setBody($theme-&gt;fetch('index'));
     }
 }

?&gt;

</pre>
    <p>Dưới đây là giải thích </p>
    <ul>
      <li>Dòng 10: <code>$theme = SpicaContext::getTheme();</code> giúp tạo ra một đối
      tượng của lớp <code>SpicaPageLayout</code>, cho phép nạp các tài nguyên của một theme
      cụ thể đã được cấu hình ở hệ thống cấu hình trung tâm <code>config.php</code>.
      </li>
      <li>Dòng 12: <code>$theme-&gt;attachCss('index');</code> yêu cầu framework chỉ định nạp một file
      nằm ở <code>apps/default/view/theme/my_theme/css/index.css.php</code> vào layout page khi
      được yêu cầu (tức là khi <code>loadCss()</code> được gọi).
      </li>
      <li>Dòng 13: <code>$theme-&gt;attachMeta('index');</code> yêu cầu framework chỉ định nạp một file
      nằm ở <code>apps/default/view/theme/my_theme/meta/index.meta.php</code> vào layout page khi
      được yêu cầu (tức là khi <code>loadMeta()</code> được gọi).
      </li>
      <li>Dòng 14: <code>$theme-&gt;attachScript('index');</code> yêu cầu framework chỉ định nạp một file
      nằm ở <code>apps/default/view/theme/my_theme/js/index.js.php</code> vào layout page khi
      được yêu cầu (tức là khi <code>loadScript()</code> được gọi).
      </li>
      <li>Dòng 15: <code>$theme-&gt;fetch('index')</code> sẽ cho phép định vị và nạp layout
      page có tên là index, tức là đọc và đánh giá nội dung có chứa PHP của file <code>index.tpl.php</code>.
      File này nằm ở <code>apps/default/view/theme/my_theme/layout/index.tpl.php</code> với nội dung giống như
      những gì mà chúng ta đã tạo ra.</li>
    </ul>
    <p>Như vậy là với controller như thế này, chúng ta cần có thêm một số file mới:</p>
    <ul>
      <li>File <code>apps/default/view/theme/my_theme/css/index.css.php</code> với nội dung:

<pre class="brush: css">
&lt;link rel="stylesheet" type="text/css" href="&lt;?php echo SpicaContext::getCssPath(); ?&gt;/global.css"  media="screen" /&gt;
&lt;style type="text/css"&gt;
body {
  background: #C6E2EE;
}
</pre>

      <p>Khi file layout page được nạp thì nội dung trên sẽ được đưa vào đúng vị trí có lời gọi <code>loadCss()</code></p>
      </li>
      <li>File <code>apps/default/view/theme/my_theme/meta/index.meta.php</code> với nội dung:

<pre class="brush: css;">
&lt;meta content="Spica is a simple but powerful and very fast framework" /&gt;
</pre>

      <p>Khi file layout page được nạp thì nội dung trên sẽ được đưa vào đúng vị trí có lời gọi <code>loadMeta()</code></p>
      </li>
      <li>File <code>apps/default/view/theme/my_theme/js/index.js.php</code> với nội dung:
<pre class="brush: js;">
&lt;script type="text/javascript"&gt;
  var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
&lt;/script&gt;
</pre>
      <p>Khi file layout page được nạp thì nội dung trên sẽ được đưa vào đúng vị trí có lời gọi <code>loadScript()</code></p>
      </li>
    </ul>
    <p>Đây là các file mẫu với nội dung mẫu để giúp hình dung về cách hoạt động của framework. Quý vị có thể thay đổi tên
    file và nội dung để xem Spica phản ứng ra sao. Ví dụ: tạo ra một file rỗng có tên là
    <code>apps/default/view/theme/my_theme/js/index2.js.php</code> và gọi nó từ Controller là
    <code>$theme-&gt;attachScript('index2');</code>
    </p>

    <p>Bây giờ duyệt đến địa chỉ <code>http://localhost/spica/</code><code class="o">sample/print/helloworld</code>, quý vị
     sẽ thấy một trang web với page title là <strong>Simple theme</strong> hiện lên</p>

     <h3>Theme, block và block group</h3>
     <p>Ví dụ trên đã cho quý vị thấy cách thức mà Spica cấu hình để sử dụng theme cũng như các
     bước để xây dựng nên một theme có tên là <code>my_theme</code>. Tuy nhiên, ví dụ chưa cho thấy
     theme tạo ra cách thức để các controller chia sẻ cấu trúc trang chung như thế nào. Spica
     khuyến khích tăng cường tính modular cho ứng dụng bằng việc chia nhỏ trang thành
     các thành phần lắp ghép (building blocks): block và blockgroup.
     Một block hay blockgroup sau khi đã được tạo ra có thể dùng đi dùng lại để ghép thành
     nhiều layout page. Trong phần này, chúng ta sẽ cùng nhau làm các việc sau: </p>
     <ul>
       <li>Tạo ra 2 page cùng dùng một theme</li>
       <li>Sử dụng khái niệm block, blockgroup</li>
     </ul>
     <p>Chúng ta sẽ thay thế nội dung của file <code>apps/default/view/theme/my_theme/layout/index.tpl.php</code> bằng code sau </p>

<pre class="brush: php; highlight: [8, 9, 13, 15, 17, 20]">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
&lt;?php echo spica_view_base_tag(); ?&gt;
&lt;title&gt;&lt;?php echo $this-&gt;pageTitle; ?&gt;&lt;/title&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;
&lt;link rel="stylesheet" href="public/spica/css/reset.css" type="text/css" media="all" /&gt;
&lt;?php $this-&gt;loadMeta(); ?&gt;
&lt;?php $this-&gt;loadCss(); ?&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="wrapper"&gt;
  &lt;?php echo $this-&gt;fetchBlock('SampleHeaderBlock'); ?&gt;
  &lt;div id="main"&gt;
  &lt;?php echo $this-&gt;fetchBody(); ?&gt;
  &lt;/div&gt;
  &lt;?php echo $this-&gt;fetchBlock('SampleFooterBlock'); ?&gt;
&lt;/div&gt;
&lt;script type="text/javascript" src="public/spica/js/spica.js"&gt;&lt;/script&gt;
&lt;?php echo $this-&gt;loadScript(); ?&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
    <p>Quý vị có thể thấy những chỗ trước kia chúng ta để là HTML thì nay đã được thay thế bằng PHP
    với các API đặc thù. Cụ thể:</p>
    <ul>
      <li><code>&lt;div&gt;Header of the page&lt;/div&gt;</code> được thay bằng
      <code>&lt;?php echo $this-&gt;fetchBlock('SampleHeaderBlock'); ?&gt;</code></li>
      <li><code>&lt;div&gt;Footer of the page&lt;/div&gt;</code> được thay bằng
      <code>&lt;?php echo $this-&gt;fetchBlock('SampleFooterBlock'); ?&gt;</code></li>
      <li><code>&lt;div&gt;Main body content of the page&lt;/div&gt;</code> được thay bằng
      <code>&lt;?php echo $this-&gt;fetchBody(); ?&gt;</code></li>
    </ul>
    <p>Xin được giải thích như sau:</p>
    <ul>
      <li>Dòng 8: <code>&lt;?php $this-&gt;loadMeta(); ?&gt;</code>: nghĩa là nạp đoạn
      mã meta tag nằm trong file được chỉ định tại controller.</li>
      <li>Dòng 9: <code>&lt;?php $this-&gt;loadCss(); ?&gt;</code>: nghĩa là nạp đoạn
      mã style tag hay link nằm trong file được chỉ định tại controller để đưa nội dung CSS vào.</li>
      <li>Dòng 13: <code>&lt;?php $this-&gt;fetchBlock('SampleHeaderBlock'); ?&gt;</code>:
      nghĩa là nạp nội dung (HTML hay text) của một block (vùng) có tên
      là <code>SampleHeaderBlock</code> vào. Đây là tên một file/lớp nằm trong
      thư mục <code>apps/default/block</code></li>
      <li>Dòng 15: <code>&lt;?php $this-&gt;fetchBody(); ?&gt;</code>:
      nghĩa là nạp nội dung mà controller chỉ định vào. Do vùng nội dung này thay đổi
      theo từng Controller nên trang có cách trình theo layout này cũng thay đổi tại vị trí này.
      Nội dung này thường được cấp bởi một file nằm trong thư mục <code>apps/default/block</code> hay
      <code>apps/default/block/group</code>. Nhưng tên file là gì thì phải qua Controller chỉ định. </li>
      <li>Dòng 17: <code>&lt;?php $this-&gt;fetchBlock('SampleFooterBlock'); ?&gt;</code>:
      nghĩa là nạp nội dung (HTML hay text) của một block (vùng) có tên
      là <code>SampleFooterBlock</code> vào. Đây là tên một file/lớp nằm trong thư mục <code>apps/default/block</code></li>
      <li>Dòng 8: <code>&lt;?php $this-&gt;loadScript(); ?&gt;</code>: nghĩa là nạp các file
      chứa mã JavaScript (nằm trong các script tag) được chỉ định tại controller.</li>
    </ul>
    <p>Mục tiêu của việc thay thế này là để tạo ra các vùng dữ liệu động có thể thay đổi
    theo từng URL cụ thể.</p>
    <h4>Tạo lớp để tách header của trang</h4>
    <p>Để <code>&lt;?php $this-&gt;fetchBlock('SampleHeaderBlock'); ?&gt;</code> hoạt động, chúng ta sẽ tạo
    ra một file có tên là <code>SampleHeaderBlock.php</code> nằm trong <code>apps/default/block</code> với
    nội dung: </p>

<pre class="brush: php;">
&lt;?php

class SampleHeaderBlock extends SpicaPageBlock
{
    protected $_templateFile = 'sampleHeader';
}

?&gt;
</pre>
    <p>Dòng <code>protected $_templateFile = 'sampleHeader';</code> cho thấy lớp này sẽ nạp một
    file template có tên là <code>sampleHeader.tpl.php</code> nằm trong <code>apps/default/view/theme/my_theme/block</code>.
    Chúng ta sẽ cho template này có nội dung như sau: </p>
<pre class="brush: php;">
&lt;div&gt;Header of the page&lt;/div&gt;
</pre>
   <p>Khi layout tempalte file được nạp thì mã HTML nêu trên sẽ được nạp vào đúng
   chỗ của lời gọi <code>&lt;?php $this-&gt;fetchBlock('SampleHeaderBlock'); ?&gt;</code>
   </p>
   <h4>Tạo lớp để tách footer của trang</h4>
   <p>Tương tự, để <code>&lt;?php $this-&gt;fetchBlock('SampleFooterBlock'); ?&gt;</code> hoạt động, chúng ta sẽ tạo
    ra một file có tên là <code>SampleFooterBlock.php</code> nằm trong <code>apps/default/block</code> với
    nội dung: </p>

<pre class="brush: php;">
&lt;?php

class SampleFooterBlock extends SpicaPageBlock
{
    protected $_templateFile = 'sampleFooter';
}

?&gt;
</pre>
    <p>Dòng <code>protected $_templateFile = 'sampleFooter';</code> cho thấy lớp này sẽ nạp một
    file template có tên là <code>sampleFooter.tpl.php</code> nằm trong <code>apps/default/view/theme/my_theme/block</code>.
    Chúng ta sẽ cho template này có nội dung như sau: </p>
<pre class="brush: php;">
&lt;div&gt;Footer of the page&lt;/div&gt;
</pre>
   <p>Khi layout tempalte file được nạp thì mã HTML nêu trên sẽ được nạp vào đúng
   chỗ của lời gọi <code>&lt;?php $this-&gt;fetchBlock('SampleFooterBlock'); ?&gt;</code>
   </p>

   <h4>Nội dung động trong layout page qua sự điều khiển của Controller</h4>
   <p>Để code <code>&lt;?php $this-&gt;fetchBody(); ?&gt;</code> hoạt động, chúng ta cần thay đổi
   nội dung của Controller như sau: </p>

<pre class="brush: php; highlight: [15]">
&lt;?php

/**
 * &quot;Hello World&quot; program controller.
 */
 class Welcome_SamplePrint
 {
     public function helloworldAction()
     {
        $theme = SpicaContext::getTheme();
        $theme-&gt;pageTitle = 'Simple theme';
        $theme-&gt;attachCss('index');
        $theme-&gt;attachMeta('index');
        $theme-&gt;attachScript('index');
        $theme-&gt;setBody('SampleBlockGroup');
        SpicaResponse::setBody($theme-&gt;fetch('index'));
     }
 }

?&gt;

</pre>
    <p>Dòng <code>$theme-&gt;setBody('SampleBlockGroup');</code> chỉ định framework
    hãy chạy lớp có tên là <code>SampleBlockGroup</code> nằm tại <code>apps/default/blockgroup/SampleBlockGroup.php</code>
    và trả lại nội dung của nó tại nơi có lời gọi <code>&lt;?php $this-&gt;fetchBody(); ?&gt;</code>
    trên layout page.</p>
    <p>Để <code>$theme-&gt;setBody('SampleBlockGroup');</code> hoạt động được chúng ta hãy
    tạo ra một file có tên <code>SampleBlockGroup.php</code> nằm ở <code>apps/default/blockgroup</code> với nội dung</p>

<pre class="brush: php; highlight: [5]">
&lt;?php

class SampleBlockGroup extends SpicaPageBlockGroup
{
    protected $_templateFile = 'sampleBody';

    public function beforeInitialization()
    {

    }

    public function initialize()
    {

    }
}

?&gt;
</pre>
    <p>Dòng <code>protected $_templateFile = 'sampleBody';</code> cho thấy lớp này sẽ nạp một
    file template có tên là <code>sampleBody.tpl.php</code> nằm trong <code>apps/default/view/theme/my_theme/blockgroup</code>.
    Chúng ta sẽ cho template này có nội dung như sau: </p>
<pre class="brush: php;">
&lt;div&gt;Main body content of the page&lt;/div&gt;
</pre>
   <p>Khi layout tempalte file được nạp thì mã HTML nêu trên sẽ được nạp vào đúng
   chỗ của lời gọi <code>&lt;?php $this-&gt;fetchBody(); ?&gt;</code>
   </p>

    <?php echo $this->fetchBlock('welcome/SpicaDocsNoteBlock'); ?>